import { isArray, map, includes, each, difference } from "lodash";
import React, { useMemo } from "react";
import { Section, Input, Checkbox, Select } from "@/components/visualizations/editor";
import { UpdateOptionsStrategy } from "@/components/visualizations/editor/createTabbedEditor";
import { EditorPropTypes } from "@/visualizations/prop-types";
import ColumnMappingSelect from "./ColumnMappingSelect";

function getMappedColumns(options, availableColumns) {
  const mappedColumns = {};
  const availableTypes = includes(['tree','trees','treeselect','treeselects'], options.listStyle) ? ["x", "y", "parent"] : ["x", "y"];
  each(availableTypes, type => {
    mappedColumns[type] = ColumnMappingSelect.MappingTypes[type].multiple ? [] : null;
  });

  availableColumns = map(availableColumns, c => c.name);
  const usedColumns = [];

  each(options.columnMapping, (type, column) => {
    if (includes(availableColumns, column) && includes(availableTypes, type)) {
      const { multiple } = ColumnMappingSelect.MappingTypes[type];
      if (multiple) {
        mappedColumns[type].push(column);
      } else {
        mappedColumns[type] = column;
      }
      usedColumns.push(column);
    }
  });

  return {
    mappedColumns,
    unusedColumns: difference(availableColumns, usedColumns),
  };
}

function mappedColumnsToColumnMappings(mappedColumns) {
  const result = {};
  each(mappedColumns, (value, type) => {
    if (isArray(value)) {
      each(value, v => {
        result[v] = type;
      });
    } else {
      if (value) {
        result[value] = type;
      }
    }
  });
  return result;
}

export default function GeneralSettings({ options, data, visualizationName, onOptionsChange }) {
  const { mappedColumns, unusedColumns } = useMemo(() => getMappedColumns(options, data.columns), [
    options,
    data.columns,
  ]);

  function handleColumnMappingChange(column, type) {
    const columnMapping = mappedColumnsToColumnMappings({
      ...mappedColumns,
      [type]: column,
    });
    onOptionsChange({ columnMapping }, UpdateOptionsStrategy.shallowMerge);
  }

  return (
    <React.Fragment>
      <Section>
        <label>列表类型：</label>
        <Select
          defaultValue={options.listStyle}
          onChange={value => onOptionsChange({ listStyle: value })}
        >
          <Select.Option key="list">列表</Select.Option>
          <Select.Option key="dropdown">下拉单选</Select.Option>
          <Select.Option key="dropdowns">下拉多选</Select.Option>
          <Select.Option key="button">开关单选</Select.Option>
          <Select.Option key="radioh">按钮单选（水平）</Select.Option>
          <Select.Option key="radiov">按钮单选（垂直）</Select.Option>
          <Select.Option key="checkboxsh">勾选多选（水平）</Select.Option>
          <Select.Option key="checkboxsv">勾选多选（垂直）</Select.Option>
          <Select.Option key="tree">树单选</Select.Option>
          <Select.Option key="trees">树多选</Select.Option>
          <Select.Option key="treeselect">下拉树单选</Select.Option>
          <Select.Option key="treeselects">下拉树多选</Select.Option>
        </Select>
      </Section>
      <Section hidden={includes(['tree','trees'], options.listStyle)}>
        <label>前置标题：</label>
        <Input
          defaultValue={options.title}
          title="支持HTML5语法"
          onChange={e => onOptionsChange({ title: e.target.value })}
        />
      </Section>
      {map(mappedColumns, (value, type) => (
        <ColumnMappingSelect
          key={type}
          type={type}
          value={value}
          areAxesSwapped={options.swappedAxes}
          availableColumns={unusedColumns}
          onChange={handleColumnMappingChange}
        />
      ))}
      <Section>
        <Checkbox
          data-test="Chart.DataLabels.ParentCheckbox"
          disabled={!['trees','treeselects'].includes(options.listStyle)}
          defaultChecked={options.parentCheckbox}
          onChange={event => onOptionsChange({ parentCheckbox: event.target.checked })}>
          允许非末级节点勾选
        </Checkbox>
      </Section>
      <Section>
        <Checkbox
          data-test="Chart.DataLabels.ClickEnabled"
          defaultChecked={options.clickEnabled}
          onChange={event => onOptionsChange({ clickEnabled: event.target.checked })}>
          支持区域点击
        </Checkbox>
        <Select
          label="点击返回值列"
          mode="default"
          showSearch
          placeholder="请选择列..."
          disabled={!options.clickEnabled}
          value={options.clickColumn || undefined}
          onChange={value => onOptionsChange({ clickColumn: value })}
        >
          <Select.Option key='' value=''>
          </Select.Option>
          {data.columns.map(item => (  
            <Select.Option key={item.name} value={item.name}>
            {item.friendly_name}
            </Select.Option>
          ))}
        </Select>
        <Input
          label="点击返回参数名"
          disabled={!options.clickEnabled}
          defaultValue={options.clickParameter}
          onChange={e => onOptionsChange({ clickParameter: e.target.value })}
        />
        <Select
          label="多选返回值引号"
          disabled={!options.clickEnabled || !['dropdowns','checkboxsh','checkboxsv','trees','treeselects'].includes(options.listStyle)}
          defaultValue={options.quoteOption}
          onChange={value => onOptionsChange({ quoteOption: value })}
        >
          <Option value="">无引号(默认)</Option>
          <Option value="'">单引号</Option>
          <Option value={'"'}>双引号</Option>
        </Select>
      </Section>
    </React.Fragment>
  );
}

GeneralSettings.propTypes = EditorPropTypes;
